<?php
/*
 * @Description    : 异常
 * @Version        : 1.0.0
 * @Author         : QianLong
 * @Date           : 2021-04-08 21:27:23
 * @LastEditors    : QianLong
 * @LastEditTime   : 2023-07-07 16:17:58
 */

namespace app\lib\exception;

use think\exception\Handle;
use think\exception\HttpException;
use think\exception\ValidateException;
use think\Response;
use Throwable;
use ErrorException;
use Exception;
use InvalidArgumentException;
use ParseError;
//use PDOException;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\ClassNotFoundException;
use think\exception\HttpResponseException;
use think\exception\RouteNotFoundException;
use TypeError;
use app\lib\Result;
use think\facade\Env;

class Http extends Handle
{
    public function render($request, Throwable $e): Response
    {
        $requestId = createId('LRE');
        //如果处于调试模式
        // if (Env('app_debug')){
        //     return parent::render($request, $e);
        // }
        // 参数验证错误
        if ($e instanceof ValidateException) {
            return Result::Error($e->getError(),422);
        }
        if ($e instanceof ApiException) {
            return Result::Error($e->getMessage(),$e->getCode());
        }

        // 请求404异常 , 不返回错误页面
        if (($e instanceof ClassNotFoundException || $e instanceof RouteNotFoundException) || ($e instanceof HttpException && $e->getStatusCode() == 404)) {
            return Result::Error('当前请求的资源不存在，请稍后再试 '.$e->getMessage(),404);
        }

        //请求500异常, 不返回错误页面
        //$e instanceof PDOException ||
        if ($e instanceof Exception ||  $e instanceof HttpException || $e instanceof InvalidArgumentException || $e instanceof ErrorException || $e instanceof ParseError || $e instanceof TypeError)  {
               $this->reportException($request,$e, $requestId);
               return Result::Error('系统异常，请稍后再试 [ErrorId：'. $requestId.']',500);
        }
        //其他错误
        $this->reportException($request,$e, $requestId);
        return Result::Error('应用发生错误 [ErrorId：'.$requestId.']',1);
    }

    //记录exception到日志
    private function reportException($request, Throwable$e, $requestId):void {
        $logData['time'] = date('Y-m-d H:i:s');
        $logData['request_id'] = $requestId;
        $logData['url'] = $request->url(true);
        $logData['param'] = $request->param(false);
        $logData['file'] = $e->getFile() . ' ; Line: ' . $e->getLine();
        $logData['message'] = $e->getMessage();
        $logData['http_code'] = $e->getCode();
        $logData['trace'] = $e->getTraceAsString();
        $logData['client_ip'] = get_client_ip();
        doLogPush($logData);
    }

}